package com.luoboduner.moo.tool.ui.dialog.JsonVmDialog;

import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.icons.FlatSearchIcon;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.luoboduner.moo.tool.App;
import com.luoboduner.moo.tool.dao.TJsonVmMapper;
import com.luoboduner.moo.tool.domain.TJsonVm;
import com.luoboduner.moo.tool.ui.UiConsts;
import com.luoboduner.moo.tool.ui.component.RTextSyntaxText.RTextSyntaxText;
import com.luoboduner.moo.tool.ui.form.MainWindow;
import com.luoboduner.moo.tool.util.ComponentUtil;
import com.luoboduner.moo.tool.util.JTableUtil;
import com.luoboduner.moo.tool.util.MybatisUtil;
import com.luoboduner.moo.tool.util.SqliteUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Date;
import java.util.List;
/**
 * @author Liutime
 */
@Getter
@Slf4j
public class JsonVmDialog extends JDialog {

  public static TJsonVmMapper jsonVmMapper = MybatisUtil.getSqlSession().getMapper(TJsonVmMapper.class);


  private JTable table1;

  private JTextField textField1;


  private JPanel jsonVmPanel;

  private JSplitPane splitPane;

  private JPanel rightPanel;

  private JPanel textAreaContent;

  private boolean ignoreQuickSave;

  private String selectedNameJson;

  /**
   * 这了是new出来的。如果弹框关闭，这个需要销毁吗？
   * static 导致该类一加载 就会初始化，
   */
  private static RTextSyntaxText json = new RTextSyntaxText("java", "");


  public JsonVmDialog() {
    super(App.mainFrame, "Vm");
    initUi();
    initListTable();

    inintEvent();
    ComponentUtil.setPreferSizeAndLocateToCenter(this, 0.6, 0.8);
    setContentPane(jsonVmPanel);
    setModal(true);

  }

  private void inintEvent() {
    /*
    搜索框变更事件
     */
    textField1.getDocument().addDocumentListener(new DocumentListener() {
      @Override
      public void insertUpdate(DocumentEvent e) {
        initListTable();
      }

      @Override
      public void removeUpdate(DocumentEvent e) {
        initListTable();
      }

      @Override
      public void changedUpdate(DocumentEvent e) {
//                initListTable();
      }
    });


    /*
    文本域按键事件
     */
    json.getTextArea().addKeyListener(new KeyListener() {
      @Override
      public void keyReleased(KeyEvent arg0) {
      }

      @Override
      public void keyPressed(KeyEvent evt) {
                /*
                1. Ctrl/Cmd + S → 快速保存
                evt.isControlDown() || evt.isMetaDown()
                Windows/Linux 使用 Ctrl 键
                macOS 使用 Cmd 键（对应 Meta）
                 */
        //
        if ((evt.isControlDown() || evt.isMetaDown()) && evt.getKeyCode() == KeyEvent.VK_S) {
          quickSave(true); // 调用快速保存方法，参数 true 可能表示自动保存

                    /*
                    2. 格式化 JSON 快捷键
                    Ctrl/Cmd + Shift + F 或 ​Cmd + Alt + L
                     */
        } else if (
            ((evt.isControlDown() || evt.isMetaDown()) && evt.isShiftDown() && evt.getKeyCode() == KeyEvent.VK_F) ||
                (evt.isMetaDown() && evt.isAltDown() && evt.getKeyCode() == KeyEvent.VK_L)
        ) {

//          String jsonText = json.getTextArea().getText(); // 获取原始文本
//          json.getTextArea().setText(formatJson(jsonText)); // 格式化后回填
//          json.getTextArea().setCaretPosition(0); // 光标复位到开头

                    /*
                    3. Ctrl/Cmd + F → 查找
                     */
        } else if ((evt.isControlDown() || evt.isMetaDown()) && evt.getKeyCode() == KeyEvent.VK_F) {
//          showFindPanel(); // 显示查找面板

                    /*
                    4. Ctrl/Cmd + R → 当前代码也触发查找（可能预期是替换功能，需确认）
                     */
        } else if ((evt.isControlDown() || evt.isMetaDown()) && evt.getKeyCode() == KeyEvent.VK_R) {
//          showFindPanel(); // 可能与 Ctrl+F 重复，疑似代码待完善

                    /*
                    5. Ctrl/Cmd + N → 新建 JSON
                     */
        } else if ((evt.isControlDown() || evt.isMetaDown()) && evt.getKeyCode() == KeyEvent.VK_N) {
          newJson(); // 清空或新建文档
        }
      }

      @Override
      public void keyTyped(KeyEvent arg0) {
      }
    });


    /*
    左侧列表按键事件（重命名）
     */
    table1.addKeyListener(new KeyListener() {
      @Override
      public void keyTyped(KeyEvent e) {

      }

      @Override
      public void keyPressed(KeyEvent evt) {

      }

      @Override
      public void keyReleased(KeyEvent evt) {
        // 1. Enter 键：保存重命名
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
          // 获取表格选中行
          int selectedRow = table1.getSelectedRow();

          // 从表格中提取笔记ID和名称
          int noteId = Integer.parseInt(String.valueOf(
              table1.getValueAt(selectedRow, 0))); // 第一列为ID
          String name = String.valueOf(
              table1.getValueAt(selectedRow, 1));  // 第二列为名称

          // 名称非空校验
          if (StringUtils.isNotBlank(name)) {
            TJsonVm tJsonBeauty = new TJsonVm();
            tJsonBeauty.setId(noteId);
            tJsonBeauty.setName(name);

            try {
              // 更新数据库（选择性更新非空字段）
              jsonVmMapper.updateByPrimaryKeySelective(tJsonBeauty);
            } catch (Exception e) {
              // 失败处理：提示用户并刷新表格
              JOptionPane.showMessageDialog(App.mainFrame, "重命名失败，和已有文件重名");
              initListTable(); // 重新加载表格数据
              log.error(e.toString());         // 记录错误日志（建议打印完整堆栈）
            }
          }

          // 2. Delete 键：删除笔记
        } else if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
          deleteFiles(table1); // 调用删除方法（需实现）

          // 3. ↑/↓ 方向键：切换笔记并查看内容
        } else if (evt.getKeyCode() == KeyEvent.VK_UP || evt.getKeyCode() == KeyEvent.VK_DOWN) {
          int selectedRow = table1.getSelectedRow();
          ignoreQuickSave = true; // 临时禁用自动保存
          try {
            viewByRowNum(selectedRow); // 根据行号加载内容（如显示JSON文本）
          } catch (Exception e) {
            log.error(e.getMessage()); // 记录错误（建议更详细日志）
          } finally {
            ignoreQuickSave = false; // 恢复自动保存
          }
        }
      }
    });



    /*
    左侧列表点击事件
     */
    table1.addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        super.mousePressed(e);

        int focusedRowIndex = table1.rowAtPoint(e.getPoint());
        if (focusedRowIndex == -1) {
          return;
        }

        ignoreQuickSave = true;
        try {
          viewByRowNum(focusedRowIndex);
        } catch (Exception e2) {
          log.error(e2.getMessage());
        } finally {
          ignoreQuickSave = false;
        }
      }
    });
  }

  private void newJson() {
    String name = "未命名_" + DateFormatUtils.format(new Date(), "yyyy-MM-dd_HH-mm-ss");
    name = JOptionPane.showInputDialog(MainWindow.getInstance().getMainPanel(), "名称", name);
    if (StringUtils.isNotBlank(name)) {
      TJsonVm tJsonBeauty = jsonVmMapper.selectByName(name);
      if (tJsonBeauty == null) {
        tJsonBeauty = new TJsonVm();
      } else {
        JOptionPane.showMessageDialog(App.mainFrame, "存在同名文件，请重新命名！", "提示", JOptionPane.INFORMATION_MESSAGE);
        return;
      }
      String now = SqliteUtil.nowDateForSqlite();
      tJsonBeauty.setName(name);
      tJsonBeauty.setCreateTime(now);
      tJsonBeauty.setModifiedTime(now);
      jsonVmMapper.insert(tJsonBeauty);
      initListTable();
    }
  }

  private void viewByRowNum(int selectedRow) {

    String name = table1.getValueAt(selectedRow, 1).toString();
    selectedNameJson = name;
    setContentByName(name);
  }

  private void setContentByName(String name) {

    // 2. 根据名称从数据库查询 JSON 数据
    TJsonVm tJsonBeauty = jsonVmMapper.selectByName(name);

    // 3. 将查询到的 JSON 内容设置到文本区域
    json.getTextArea().setText(tJsonBeauty.getContent());

    // 4. 重置光标位置到文本开头
    json.getTextArea().setCaretPosition(0);

    // 5. 重置垂直滚动条到顶部
    json.getRTextScrollPane().getVerticalScrollBar().setValue(0);

    // 6. 重置水平滚动条到最左
    json.getRTextScrollPane().getHorizontalScrollBar().setValue(0);

  }

  private void quickSave(boolean refreshModifiedTime) {
    String now = SqliteUtil.nowDateForSqlite();
    if (selectedNameJson != null) {
      TJsonVm tJsonBeauty = new TJsonVm();
      tJsonBeauty.setName(selectedNameJson);
      tJsonBeauty.setContent(json.getTextArea().getText());
      if (refreshModifiedTime) {
        tJsonBeauty.setModifiedTime(now);
      }
      jsonVmMapper.updateByName(tJsonBeauty);
    } else {
      String tempName = "未命名_" + DateFormatUtils.format(new Date(), "yyyy-MM-dd_HH-mm-ss");
      String name = JOptionPane.showInputDialog(MainWindow.getInstance().getMainPanel(), "名称", tempName);
      if (StringUtils.isNotBlank(name)) {
        TJsonVm tJsonBeauty = new TJsonVm();
        tJsonBeauty.setName(name);
        tJsonBeauty.setContent(json.getTextArea().getText());
        tJsonBeauty.setCreateTime(now);
        tJsonBeauty.setModifiedTime(now);

        jsonVmMapper.insert(tJsonBeauty);
        initListTable();
        selectedNameJson = name;
      }
    }
  }

  private void initListTable() {
    String[] headerNames = {"id", "名称"};
    DefaultTableModel model = new DefaultTableModel(null, headerNames);
    table1.setModel(model);
    // 隐藏表头
    JTableUtil.hideTableHeader(table1);
    // 隐藏id列
    JTableUtil.hideColumn(table1, 0);

    Object[] data;

    String titleFilterKeyWord = textField1.getText();
    titleFilterKeyWord = "%" + titleFilterKeyWord + "%";

    List<TJsonVm> jsonBeautyList = jsonVmMapper.selectByFilter(titleFilterKeyWord);
    for (TJsonVm tJsonBeauty : jsonBeautyList) {
      data = new Object[2];
      data[0] = tJsonBeauty.getId();
      data[1] = tJsonBeauty.getName();
      model.addRow(data);
    }
        /*
        默认选中第一行
         */
    if (jsonBeautyList.size() > 0) {
      ignoreQuickSave = true;
      try {
        selectedNameJson = jsonBeautyList.get(0).getName();
        json.getTextArea().setText(jsonBeautyList.get(0).getContent());
        table1.setRowSelectionInterval(0, 0);
      } catch (Exception e2) {
        log.error(e2.getMessage());
      } finally {
        ignoreQuickSave = false;
      }

    }
  }

  private void initUi() {
    textField1.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "搜索");
    textField1.putClientProperty(FlatClientProperties.TEXT_FIELD_LEADING_ICON,
        new FlatSearchIcon());

    /*
        表格行高
         */
    table1.setRowHeight(UiConsts.TABLE_ROW_HEIGHT);

        /*
    根据后缀名匹配
     */
    textAreaContent.add(json.getContentPane());

        /*
        文本聚焦
         */
    json.getTextArea().grabFocus();


    /*
        刷新
    */
    jsonVmPanel.updateUI();

  }


  private void deleteFiles(JTable jTable) {
    try {
      int[] selectedRows = jTable.getSelectedRows();

      if (selectedRows.length == 0) {
        JOptionPane.showMessageDialog(App.mainFrame, "请至少选择一个！", "提示", JOptionPane.INFORMATION_MESSAGE);
      } else {
        int isDelete = JOptionPane.showConfirmDialog(App.mainFrame, "确认删除？", "确认", JOptionPane.YES_NO_OPTION);
        if (isDelete == JOptionPane.YES_OPTION) {
          DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();

          for (int i = 0; i < selectedRows.length; i++) {
            int selectedRow = selectedRows[i];
            Integer id = (Integer) tableModel.getValueAt(selectedRow, 0);
            jsonVmMapper.deleteByPrimaryKey(id);
          }
          selectedNameJson = null;
          initListTable();
        }
      }
    } catch (Exception e1) {
      JOptionPane.showMessageDialog(App.mainFrame, "删除失败！\n\n" + e1.getMessage(), "失败",
          JOptionPane.ERROR_MESSAGE);
      log.error(e1.toString());
    }
  }


  {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
    $$$setupUI$$$();
  }

  /**
   * Method generated by IntelliJ IDEA GUI Designer
   * >>> IMPORTANT!! <<<
   * DO NOT edit this method OR call it in your code!
   *
   * @noinspection ALL
   */
  private void $$$setupUI$$$() {
    jsonVmPanel = new JPanel();
    jsonVmPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
    splitPane = new JSplitPane();
    jsonVmPanel.add(splitPane, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(200, 200), null, 0, false));
    final JPanel panel1 = new JPanel();
    panel1.setLayout(new GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1));
    splitPane.setLeftComponent(panel1);
    textField1 = new JTextField();
    panel1.add(textField1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false));
    final JScrollPane scrollPane1 = new JScrollPane();
    panel1.add(scrollPane1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
    table1 = new JTable();
    scrollPane1.setViewportView(table1);
    rightPanel = new JPanel();
    rightPanel.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
    splitPane.setRightComponent(rightPanel);
    textAreaContent = new JPanel();
    textAreaContent.setLayout(new BorderLayout(0, 0));
    rightPanel.add(textAreaContent, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
  }

  /**
   * @noinspection ALL
   */
  public JComponent $$$getRootComponent$$$() {
    return jsonVmPanel;
  }

}
